package 回溯算法;

import java.util.LinkedList;
import java.util.List;

/**
 * @Author: biubiu0002
 * @Date: 2021-03-23 19:46
 **/
public class 全排列问题 {
    List<List<Integer>> res = new LinkedList<>();

    /**
     * 主函数 输入一组不重复的数字，返回他们的全排列
     * @param nums
     * @return
     */
    List<List<Integer>> permute(int[] nums){
        //记录 [路径]
        LinkedList<Integer> track = new LinkedList<>();
        backtrack(nums,track);
        return res;

    }


    // 路径：记录在 track 中
    // 选择列表：nums 中不存在于 track 的那些元素
    // 结束条件：nums 中的元素全都在 track 中出现
    void backtrack(int[]nums,LinkedList<Integer> track){
        //做选择
        //backtrack
        //撤销选择

        //触发结束条件
        if(track.size()==nums.length){
            res.add(track);
            return;
        }

        for(int i=0;i<nums.length;i++){
            //排除不合法的选择
            if(track.contains(nums[i]))
                continue;

            track.add(nums[i]);
            //进入下一层决策树
            backtrack(nums,track);
            //取消选择
            track.removeLast();
        }

    }


    public static void main(String[] args) {
        int[]nums = {1,2,3};
        全排列问题 a = new 全排列问题();
        List<List<Integer>> permute = a.permute(nums);
        System.out.println(permute);

//        System.out.println(permute);


    }

    /**
     * 回溯算法框架
     * result = []
     * def backtrack(路径, 选择列表):
     *     if 满足结束条件:
     *         result.add(路径)
     *         return
     *
     *     for 选择 in 选择列表:
     *         做选择
     *         backtrack(路径, 选择列表)
     *         撤销选择
     * @return
     */

    /**
     * for 选择 in 选择列表:
     *     # 做选择
     *     将该选择从选择列表移除
     *     路径.add(选择)
     *     backtrack(路径, 选择列表)
     *     # 撤销选择
     *     路径.remove(选择)
     *     将该选择再加入选择列表
     * @return
     */



}
